package com.yl.order.helper;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;

import com.yl.common.utils.LogUtil;
import com.yl.common.utils.ShellUtils;
import com.yl.order.App;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.android.schedulers.AndroidSchedulers;

/**
 * Created by bpb on 2020-04-09.
 * 说明：用于安装smallapk 和发送是否延后要被smallapk带起的action
 */
public class SmallApkHelper {
    public static final String ACTION_PICK_ME_UP = "CJX.PICK_ME_UP";
    public static final String ACTION_PRINT_TAG = "CJX.PRINT_TAG";
    public static final int MODE_ACTIVITY = 1;
    public static final int MODE_SERVICE = 2;
    public static final int MODE_BROADCAST = 3;

    public static final String DATA_MODE = "targetMode";
    public static final String DATA_PACKAGE_NAME = "targetPackage";
    public static final String DATA_ACTION = "targetAction";
    public static final String DATA_TIMEOUT = "targetTimeOut";

    public static final String DATA_TYPE = "DATA_TYPE";
    public static final String DATA_JSON = "DATA_JSON";
    public static boolean isAndroidSystemRoot = true;

    //在application 初始化
    public static void initAndCheckSmallApk(Context context) {
        final Context appC = context.getApplicationContext();
        boolean findRevive = false;
        PackageManager pm = appC.getPackageManager();
        // Return a List of all packages that are installed on the device.
        List<PackageInfo> packages = pm.getInstalledPackages(0);
        for (PackageInfo packageInfo : packages) {
            // 判断系统/非系统应用
            if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { // 非系统应用
                log("MainActivity.getAppList, packageInfo=" + packageInfo.packageName);
                if ("com.cjx.revive".equals(packageInfo.packageName)) {
                    findRevive = true;
                    break;
                }
            }
        }
        log("是否找到应用 " + findRevive);
        startPrintService(appC);
        if (!findRevive) {
            isAndroidSystemRoot = false;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    log("拷贝开始");
                    File dataFile = copyAssetAndWrite(appC, "revive.apk");
                    if (dataFile == null) {
                        log("安装revive失败, 找不到文件");
                        return;
                    }
                    log("开始安装revive =" + dataFile.getAbsolutePath());
                    String[] cmd = new String[]{"pm install -r " + dataFile.getAbsolutePath()};
                    ShellUtils.CommandResult result = ShellUtils.execCommand(cmd, true, false);
                    log("result.result " + result.result);
                    if (result.result != 0) {
                        isAndroidSystemRoot = false;
                    } else {
                        isAndroidSystemRoot = true;
                    }
                    AndroidSchedulers.mainThread().scheduleDirect(new Runnable() {
                        @Override
                        public void run() {
                            startReviveService(appC);
                        }
                    }, 5, TimeUnit.SECONDS);
                }
            }).start();
        } else {
            isAndroidSystemRoot = true;
            startReviveService(appC);
        }
    }

    private static File copyAssetAndWrite(Context context, String fileName) {
        try {
            boolean hasExternal = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
            File cacheDir = hasExternal ? context.getExternalCacheDir() : context.getCacheDir();
            if (!cacheDir.exists()) {
                cacheDir.mkdirs();
            }
            File outFile = new File(cacheDir, fileName);
            if (outFile.exists()) {
                outFile.delete();
                boolean res = outFile.createNewFile();
                if (!res) {
                    return null;
                }
            }
            InputStream is = context.getAssets().open(fileName);
            FileOutputStream fos = new FileOutputStream(outFile);
            byte[] buffer = new byte[1024];
            int byteCount;
            while ((byteCount = is.read(buffer)) != -1) {
                fos.write(buffer, 0, byteCount);
            }
            fos.flush();
            is.close();
            fos.close();
            return outFile;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static void startReviveService(Context context) {
        Intent severIntent = new Intent("com.cjx.revive.service.BackgroundService");
        severIntent.setPackage("com.cjx.revive");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(severIntent);
        } else {
            context.startService(severIntent);
        }
    }

    private static void startPrintService(Context context) {
        Intent severIntent = new Intent("com.cjx.print.service.BackgroundService");
        severIntent.setPackage("com.cjx.print");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(severIntent);
        } else {
            context.startService(severIntent);
        }
    }

    //准备安装更新应用前发出广播

    /**
     * @param timeDelay 毫秒
     */
    public static void pullMeLaterActivityMode(int timeDelay) {
        Intent intent = new Intent(ACTION_PICK_ME_UP);
        intent.putExtra(DATA_PACKAGE_NAME, App.app.getPackageName());
        intent.putExtra(DATA_MODE, MODE_ACTIVITY);
        intent.putExtra(DATA_TIMEOUT, timeDelay);
        App.app.sendBroadcast(intent);
    }

    public static void pullMeLaterServiceMode(Context context, String action, int timeDelay) {
        Intent intent = new Intent(ACTION_PICK_ME_UP);
        intent.putExtra(DATA_PACKAGE_NAME, context.getPackageName());
        intent.putExtra(DATA_ACTION, action);
        intent.putExtra(DATA_MODE, MODE_SERVICE);
        intent.putExtra(DATA_TIMEOUT, timeDelay);
        context.sendBroadcast(intent);
    }


    public static void pullMeLaterBroadcastMode(Context context, String action, int timeDelay) {
        Intent intent = new Intent(ACTION_PICK_ME_UP);
        intent.putExtra(DATA_PACKAGE_NAME, context.getPackageName());
        intent.putExtra(DATA_TIMEOUT, timeDelay);
        context.sendBroadcast(intent);
    }

    /**
     * @param type MODE_FORMULA=1, MODE_ORDER=2
     * @param json
     */
    public static void printService(int type, String json) {
        Intent intent = new Intent(ACTION_PRINT_TAG);
        intent.putExtra(DATA_TYPE, type);
        intent.putExtra(DATA_JSON, json);
        App.app.sendBroadcast(intent);
    }

    private static void log(String message) {
        LogUtil.getInstance().log("SMALL_APK", message);
    }
}
